package com.compty.paint.freemarker;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class FreeMarkerUtil {
	
	private final Log logger = LogFactory.getLog(FreeMarkerUtil.class);
    
    private Configuration freemarker_cfg = null;
    
    private final static String Html_Skin = "/htmlskin";

	private static FreeMarkerUtil freeMarkerUtil = new FreeMarkerUtil();

	private FreeMarkerUtil() {
	}

	public Configuration getFreemarker_cfg() {
		return freemarker_cfg;
	}

	public void setFreemarker_cfg(Configuration freemarker_cfg) {
		this.freemarker_cfg = freemarker_cfg;
	}

	public static FreeMarkerUtil getInstance() {
		return freeMarkerUtil;
	}
	
	  /**
     * 获取freemarker的配置. freemarker本身支持classpath,目录和从ServletContext获取.
     * 我们用目录的方式
     */
    protected Configuration getFreeMarkerCFG()
    {
        if (null == freemarker_cfg)
        {
            // Initialize the FreeMarker configuration;
            // - Create a configuration instance
            freemarker_cfg = new Configuration();
            freemarker_cfg.setDefaultEncoding("UTF-8"); 
            freemarker_cfg.setNumberFormat("#");
            
            // - FreeMarker支持多种模板装载方式,可以查看API文档,都很简单:路径,根据Servlet上下文,classpath等等
            //htmlskin是放在classpath下的一个目录
//            ServletContext context = ServletActionContext.getServletContext();
//			freemarker_cfg.setServletContextForTemplateLoading(context, "WEB-INF/freemarker");
            
            //htmlskin是放在classpath下的一个目录
            freemarker_cfg.setClassForTemplateLoading(this.getClass(), Html_Skin);
        }
       
        return freemarker_cfg;
    } 
    
    /**
     * 生成静态文件.
     * @param sRootDir  静态文件生成目录
     * @param templateFileName 模板文件名,相对htmlskin路径,例如"/tpxw/view.ftl"
     * @param propMap 用于处理模板的属性Object映射
     * @param htmlFilePath 要生成的静态文件的路径,相对设置中的根路径,例如 "/tpxw/1/2005/4/"
     * @param htmlFileName 要生成的文件名,例如 "1.htm"
     */
    @SuppressWarnings("unchecked")
	public boolean geneHtmlFile(String sRootDir, String templateFileName,Map propMap, String htmlFilePath,String htmlFileName )
    throws TemplateException,IOException
    {
        try
        {
            Template t = getFreeMarkerCFG().getTemplate(templateFileName);
            t.setEncoding("UTF-8");
          //如果根路径存在,则递归创建子目录
            creatDirs(sRootDir,htmlFilePath);
           
            File afile = new File(sRootDir +"/" +htmlFilePath + "/" + htmlFileName);

            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(afile),"UTF-8"));

            t.process(propMap, out);
           out.flush();
           
           out.close();
        }
        catch (TemplateException e)
        {
            logger.error("Error while processing FreeMarker template " + templateFileName,e);
            throw e;
        }
        catch (IOException e)
        {
            logger.error("Error while generate Static Html File " + htmlFileName,e);
            throw e;
        }

        return true;
    } 

    /**
     * 创建多级目录
     *
     * @param aParentDir String
     * @param aSubDir  以 / 开头
     * @return boolean 是否成功
     */
    public static boolean creatDirs(String aParentDir, String aSubDir)
    {
        File aFile = new File(aParentDir);
        if (aFile.exists())
        {
            File aSubFile = new File(aParentDir + aSubDir);
            if (!aSubFile.exists())
            {
                return aSubFile.mkdirs();
            }
            else
            {
                return true;
            }
        }
        else
        {
            return false;
        }
    }    

}
